using System.Collections;
using DG.Tweening;
using UnityEngine;

public class BallGiro : MonoBehaviour
{
	private static BallGiro instance;

	private static GameObject parentObject;

	public bool isActive = true;

	public GameObject rotationParent;

	public GameObject dummyBall;

	public ParticleSystem sparklesFloor;

	public ParticleSystem dustFloor;

	public GameObject particlesHit;

	public GameObject particlesPuff;

	public GameObject particlesSpeed;

	public AudioClip soundAppear;

	private Vector3 lookVelocity = Vector3.zero;

	private BallBehaviour ball;

	private bool freezed;

	public static BallGiro GetInstance()
	{
		if (!instance)
		{
			parentObject = GameObject.Find("BallGiro");
			if (parentObject != null)
			{
				instance = parentObject.GetComponent<BallGiro>();
			}
			else
			{
				Debug.Log("WTF : no instance found for BallGiro");
			}
		}
		return instance;
	}

	private void Start()
	{
		ball = BallBehaviour.GetInstance();
		EventManager.GameFreezeEvent += OnGameFreeze;
		EventManager.GameUnfreezeEvent += OnGameUnfreeze;
	}

	private void OnDestroy()
	{
		EventManager.GameFreezeEvent -= OnGameFreeze;
		EventManager.GameUnfreezeEvent -= OnGameUnfreeze;
	}

	private void Update()
	{
		if (!freezed && isActive && (bool)ball)
		{
			base.transform.position = ball.transform.position;
		}
	}

	public void Hide()
	{
		rotationParent.SetActive(false);
	}

	public void Show()
	{
		rotationParent.SetActive(true);
	}

	public float Appear()
	{
		float num = 0.1f;
		Show();
		StartCoroutine(AppearAnimation(num));
		return num + 0.01f;
	}

	private IEnumerator AppearAnimation(float duration)
	{
		yield return true;
		float yOffset = 1f;
		rotationParent.transform.localPosition = new Vector3(0f, yOffset, 0f);
		rotationParent.transform.DOLocalMove(Vector3.zero, duration).SetEase(Ease.InSine).OnComplete(delegate
		{
			rotationParent.transform.localPosition = Vector3.zero;
		});
		yield return new WaitForSeconds(duration);
		Audio.PlaySoundRespawn();
	}

	private void OnGameFreeze()
	{
		freezed = true;
	}

	private void OnGameUnfreeze()
	{
		freezed = false;
	}

	private void FixedUpdate()
	{
		UpdateGiro();
	}

	public void UpdateGiro()
	{
		if (freezed || !isActive || !ball)
		{
			return;
		}
		Vector3 velocity = ball.velocity;
		float velocityMagnitude = ball.velocityMagnitude;
		Vector3 angularVelocity = ball.angularVelocity;
		float f = 90f - Vector3.Angle(Vector3.up, ball.heading);
		if (angularVelocity != Vector3.zero)
		{
			lookVelocity = angularVelocity;
		}
		if (velocityMagnitude < 0.001f)
		{
			lookVelocity = Vector3.Cross(ball.heading, Vector3.down);
		}
		lookVelocity.y = 0f;
		if (lookVelocity != Vector3.zero)
		{
			float num = 0.25f;
			num = velocity.sqrMagnitude;
			float min = 0.25f;
			if (Mathf.Abs(f) > 1f)
			{
				min = 0f;
			}
			num = Mathf.Clamp(num, min, 0.25f);
			base.transform.rotation = Quaternion.Lerp(base.transform.rotation, Quaternion.LookRotation(lookVelocity.normalized), num);
		}
		Vector3 vector = angularVelocity;
		vector.y = 0f;
		Vector3 euler = Vector3.forward * vector.magnitude * 1f;
		rotationParent.transform.rotation = rotationParent.transform.rotation * Quaternion.Euler(euler);
		if (ball.initState)
		{
			lookVelocity = Vector3.Cross(ball.heading, Vector3.down);
			base.transform.rotation = Quaternion.LookRotation(lookVelocity.normalized);
		}
	}

	public void OnObjectCollision(Collision collisionInfo, float collisionIntensity)
	{
		Vector3 point = collisionInfo.contacts[0].point;
		Vector3 point2 = new Ray(base.transform.position, point - base.transform.position).GetPoint(0.5f);
		bool flag = false;
		if (point.y < base.transform.position.y - 0.1f && Mathf.Abs(base.transform.position.x - point.x) < 0.1f && Mathf.Abs(base.transform.position.z - point.z) < 0.1f)
		{
			flag = true;
		}
		GameObject gameObject = Object.Instantiate(particlesHit) as GameObject;
		gameObject.transform.position = point2;
		float num = Mathf.Lerp(0.2f, 1f, collisionIntensity * 0.8f);
		ParticleSystem[] componentsInChildren = gameObject.transform.GetComponentsInChildren<ParticleSystem>();
		foreach (ParticleSystem particleSystem in componentsInChildren)
		{
			particleSystem.startSize *= num;
			particleSystem.startLifetime *= num;
		}
		if (flag)
		{
			gameObject = Object.Instantiate(particlesPuff) as GameObject;
			gameObject.transform.position = point2;
			num = Mathf.Lerp(0.2f, 1f, collisionIntensity * 0.8f);
			ParticleSystem[] componentsInChildren2 = gameObject.transform.GetComponentsInChildren<ParticleSystem>();
			foreach (ParticleSystem particleSystem2 in componentsInChildren2)
			{
				particleSystem2.startSize *= num;
				particleSystem2.startLifetime *= num;
			}
		}
	}

	public void SetPosition(Vector3 pos)
	{
		base.transform.position = pos;
	}

	public void SetAspect(Vector3 velocity, Vector3 angularVelocity)
	{
		if (angularVelocity != Vector3.zero && velocity.magnitude > 0.01f)
		{
			lookVelocity = angularVelocity;
		}
		if (lookVelocity != Vector3.zero)
		{
			float t = 0.25f;
			base.transform.rotation = Quaternion.Lerp(base.transform.rotation, Quaternion.LookRotation(lookVelocity), t);
		}
		Vector3 euler = Vector3.forward * angularVelocity.magnitude;
		rotationParent.transform.rotation = rotationParent.transform.rotation * Quaternion.Euler(euler);
	}

	public void SetDirection(Vector3 angularVelocity)
	{
		lookVelocity = angularVelocity;
	}

	public void SetRotation(Vector3 angularVelocity)
	{
		Vector3 euler = Vector3.forward * angularVelocity.magnitude;
		rotationParent.transform.rotation = rotationParent.transform.rotation * Quaternion.Euler(euler);
	}
}
